home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Games / WHDLoad / Src / programs / DIC.asm next >
Encoding:
Assembly Source File  |  2000-07-22  |  15.7 KB  |  761 lines

  1. ;*---------------------------------------------------------------------------
  2. ;  :Program.    DIC.asm
  3. ;  :Contents.    Disk-Image-Creator
  4. ;  :Author.    Bert Jahn
  5. ;  :EMail.    wepl@kagi.com
  6. ;  :Address.    Franz-Liszt-Straße 16, Rudolstadt, 07404, Germany
  7. ;  :Version.    $Id: DIC.asm 0.20 2000/07/22 18:12:00 jah Exp jah $
  8. ;  :History.    15.05.96
  9. ;        20.06.96 returncode supp.
  10. ;        01.06.97 _LVOWaitForChar added,  check for interactive terminal added
  11. ;        17.09.98 after a disk read error and 'cancel' it does not continue
  12. ;             if last disk already reached now (reported by MrLarmer)
  13. ;        12.10.98 bugfix
  14. ;        17.01.99 recompile because error.i changed
  15. ;        11.01.00 pedantic mode and skipping tracks added
  16. ;             error handling changed
  17. ;        24.02.00 multiple tracks can be skipped now (taken from wwarp ;-)
  18. ;        21.07.00 bug: retry after diskchange fixed (Andreas Falkenhahn)
  19. ;        22.07.00 option 'Name' added (Andreas Falkenhahn)
  20. ;  :Requires.    OS V37+
  21. ;  :Copyright.    © 1996,1997,1998,1999,2000 Bert Jahn, All Rights Reserved
  22. ;  :Language.    68000 Assembler
  23. ;  :Translator.    Barfly V2.16
  24. ;  :To Do.
  25. ;---------------------------------------------------------------------------*
  26. ;##########################################################################
  27.  
  28.     INCDIR    Includes:
  29.     INCLUDE    lvo/exec.i
  30.     INCLUDE    exec/execbase.i
  31.     INCLUDE    exec/io.i
  32.     INCLUDE    exec/memory.i
  33.     INCLUDE    lvo/dos.i
  34.     INCLUDE    dos/dos.i
  35.     INCLUDE    devices/trackdisk.i
  36.  
  37.     INCLUDE    macros/ntypes.i
  38.     INCLUDE    macros/mulu32.i
  39.  
  40. ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  41.  
  42. MAXTRACKS    = 160
  43.  
  44.     STRUCTURE    Globals,0
  45.         APTR    gl_execbase
  46.         APTR    gl_dosbase
  47.         ULONG    gl_stdin
  48.         APTR    gl_rdargs
  49.         LABEL    gl_rdarray
  50.         ULONG    gl_rd_device
  51.         ULONG    gl_rd_name
  52.         ULONG    gl_rd_st
  53.         ULONG    gl_rd_size
  54.         ULONG    gl_rd_fdisk
  55.         ULONG    gl_rd_ldisk
  56.         ULONG    gl_rd_pedantic
  57.         ULONG    gl_rc
  58.         STRUCT    gl_skip,MAXTRACKS
  59.         ALIGNLONG
  60.         LABEL    gl_SIZEOF
  61.  
  62. ;##########################################################################
  63.  
  64. GL    EQUR    A4        ;a4 ptr to Globals
  65. LOC    EQUR    A5        ;a5 for local vars
  66. CPU    =    68000
  67.  
  68. Version     = 0
  69. Revision = 20
  70.  
  71.     PURE
  72.     OUTPUT    C:DIC
  73.  
  74.     IFND    .passchk
  75.     DOSCMD    "WDate >T:date"
  76. .passchk
  77.     ENDC
  78.  
  79. VER    MACRO
  80.         sprintx    "DIC %ld.%ld ",Version,Revision
  81.     INCBIN    "T:date"
  82.     ENDM
  83.  
  84.         bra    .start
  85.         dc.b    0,"$VER: "
  86.         VER
  87.         dc.b    0
  88.         dc.b    "$Id: DIC.asm 0.20 2000/07/22 18:12:00 jah Exp jah $",10,0
  89.     EVEN
  90. .start
  91.  
  92. ;##########################################################################
  93.  
  94.         move.l    #gl_SIZEOF,d0
  95.         move.l    #MEMF_CLEAR,d1
  96.         move.l    (4).w,a6
  97.         jsr    (_LVOAllocMem,a6)
  98.         tst.l    d0
  99.         beq    .nostrucmem
  100.         move.l    d0,GL
  101.         move.l    a6,(gl_execbase,GL)
  102.         move.l    #RETURN_FAIL,(gl_rc,GL)
  103.  
  104.         move.l    #37,d0
  105.         lea    (_dosname),a1
  106.         move.l    (gl_execbase,GL),a6
  107.         jsr    _LVOOpenLibrary(a6)
  108.         move.l    d0,(gl_dosbase,GL)
  109.         beq    .nodoslib
  110.  
  111.         lea    (_ver),a0
  112.         bsr    _Print
  113.  
  114.         lea    (_defdev),a0
  115.         move.l    a0,(gl_rd_device,GL)
  116.  
  117.         lea    (_template),a0
  118.         move.l    a0,d1
  119.         lea    (gl_rdarray,GL),a0
  120.         move.l    a0,d2
  121.         moveq    #0,d3
  122.         move.l    (gl_dosbase,GL),a6
  123.         jsr    (_LVOReadArgs,a6)
  124.         move.l    d0,(gl_rdargs,GL)
  125.         bne    .argsok
  126.         lea    (_readargs),a0
  127.         bsr    _PrintErrorDOS
  128.         bra    .noargs
  129. .argsok
  130.         move.l    (gl_rd_size,GL),d0
  131.         beq    .01
  132.         move.l    d0,a0
  133.         bsr    _etoi
  134.         tst.b    (a0)
  135.         beq    .0
  136.         lea    (_badsize),a0
  137.         bsr    _Print
  138.         bra    .badargs
  139. .0        move.l    d0,(gl_rd_size,GL)
  140.         lea    (_withsize),a0
  141.         move.l    d0,-(a7)
  142.         move.l    d0,-(a7)
  143.         move.l    a7,a1
  144.         bsr    _PrintArgs
  145.         addq.l    #8,a7
  146. .01
  147.         moveq    #1,d1            ;default
  148.         move.l    (gl_rd_fdisk,GL),d0
  149.         beq    .1
  150.         move.l    d0,a0
  151.         move.l    (a0),d1
  152. .1        move.l    d1,(gl_rd_fdisk,GL)
  153.  
  154.         moveq    #-1,d1            ;default - no limit
  155.         move.l    (gl_rd_ldisk,GL),d0
  156.         beq    .2
  157.         move.l    d0,a0
  158.         move.l    (a0),d1
  159. .2        move.l    d1,(gl_rd_ldisk,GL)
  160.  
  161.         tst.l    (gl_rd_name,GL)
  162.         beq    .noname
  163.         moveq    #1,d0
  164.         move.l    d0,(gl_rd_fdisk,GL)
  165.         move.l    d0,(gl_rd_ldisk,GL)
  166. .noname
  167.  
  168.     ;parse tracks
  169.         lea    (gl_skip,GL),a0
  170.         move.w    #MAXTRACKS-1,d0
  171. .pt_clr        clr.b    (a0)+
  172.         dbf    d0,.pt_clr
  173.         move.l    (gl_rd_st,GL),a0
  174.         move.l    a0,d0
  175.         beq    .pt_end
  176.  
  177. .pt_loop    bsr    .pt_getnum
  178.         move.b    (a0)+,d1
  179.         beq    .pt_single
  180.         cmp.b    #",",d1
  181.         beq    .pt_single
  182.         cmp.b    #"-",d1
  183.         beq    .pt_area
  184.         cmp.b    #"*",d1
  185.         beq    .pt_step
  186.         bra    .pt_err
  187.  
  188. .pt_single    st    (gl_skip,GL,d0.w)
  189. .pt_check    tst.b    d1
  190.         beq    .pt_end
  191.         cmp.b    #",",d1
  192.         beq    .pt_loop
  193.         bra    .pt_err
  194.         
  195. .pt_step    move.l    d0,d2            ;D2 = start
  196.         move.l    #MAXTRACKS-1,d3        ;D3 = last
  197. .pt_step0    bsr    .pt_getnum        ;D0 = skip
  198.         tst.l    d0
  199.         ble    .pt_err
  200. .pt_step1    cmp.l    d2,d3
  201.         blo    .pt_err
  202. .pt_step_l    st    (gl_skip,GL,d2.w)
  203.         add.l    d0,d2
  204.         cmp.l    d2,d3
  205.         bhs    .pt_step_l
  206.         move.b    (a0)+,d1
  207.         bra    .pt_check
  208.  
  209. .pt_area    move.l    d0,d2            ;D2 = start
  210.         bsr    .pt_getnum
  211.         move.l    d0,d3            ;D3 = last
  212.         moveq    #1,d0            ;D0 = skip
  213.         cmp.b    #"*",(a0)
  214.         bne    .pt_step1
  215.         addq.l    #1,a0
  216.         bra    .pt_step0
  217.  
  218. .pt_getnum    move.l    (a7)+,a1
  219.         move.l    a0,a3
  220.         bsr    _atoi
  221.         cmp.l    a0,a3
  222.         beq    .pt_err
  223.         cmp.l    #MAXTRACKS,d0
  224.         bhs    .pt_err
  225.         jmp    (a1)
  226.  
  227. .pt_err        lea    (_txt_badtracks),a0
  228.         bsr    _Print
  229.         bra    .badargs
  230.  
  231. .pt_end
  232.         move.l    (gl_dosbase,GL),a6
  233.         jsr    (_LVOInput,a6)
  234.         move.l    d0,(gl_stdin,GL)
  235.  
  236.         move.l    #RETURN_ERROR,(gl_rc,GL)
  237.         bsr    _Main
  238. .badargs
  239.         move.l    (gl_rdargs,GL),d1
  240.         move.l    (gl_dosbase,GL),a6
  241.         jsr    (_LVOFreeArgs,a6)
  242. .noargs
  243.         move.l    (gl_dosbase,GL),a1
  244.         move.l    (gl_execbase,GL),a6
  245.         jsr    (_LVOCloseLibrary,a6)
  246. .nodoslib
  247.         move.l    (gl_rc,GL),d7
  248.  
  249.         move.l    #gl_SIZEOF,d0
  250.         move.l    GL,a1
  251.         move.l    (gl_execbase,GL),a6
  252.         jsr    (_LVOFreeMem,a6)
  253.  
  254.         move.l    d7,d0
  255.         rts
  256.  
  257. .nostrucmem    moveq    #RETURN_FAIL,d0
  258.         rts
  259.  
  260. ;##########################################################################
  261.  
  262.     INCDIR    Sources:
  263.     INCLUDE    dosio.i
  264.         PrintLn
  265.         PrintArgs
  266.         Print
  267.         FlushOutput
  268.         CheckBreak
  269.         GetKey
  270.     INCLUDE    files.i
  271.         SaveFileMsg
  272.     INCLUDE    strings.i
  273.         CopyString
  274.         FormatString
  275.         DoString
  276.         etoi
  277.     INCLUDE    devices.i
  278.         GetDeviceInfo
  279.     INCLUDE    error.i
  280.         PrintErrorTD
  281.  
  282. ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  283.  
  284. _Main        move.l    (gl_rd_device,GL),d1
  285.         moveq    #-1,d2
  286.         move.l    (gl_dosbase,GL),a6
  287.         jsr    (_LVOInhibit,a6)
  288.  
  289.         move.l    (gl_rd_fdisk,GL),d7    ;d7 disknumber
  290.         subq.l    #1,d7
  291. .nextdisk    addq.l    #1,d7
  292.         cmp.l    (gl_rd_ldisk,GL),d7
  293.         bhi    .success
  294.  
  295.     ;check if interactive console
  296.         move.l    (gl_stdin,GL),d1
  297.         move.l    (gl_dosbase,GL),a6
  298.         jsr    (_LVOIsInteractive,a6)
  299.         tst.l    d0
  300.         beq    .readdisk
  301.  
  302.     ;prompt user to insert disk
  303.         lea    (_insdisk),a0
  304.         move.l    (gl_rd_device,GL),-(a7)
  305.         move.l    d7,-(a7)
  306.         move.l    a7,a1
  307.         bsr    _PrintArgs
  308.         addq.l    #8,a7
  309.         bsr    _FlushOutput
  310.         move.l    (gl_stdin,GL),d1
  311.         move.l    (gl_dosbase,GL),a6
  312.         jsr    (_LVOFlush,a6)
  313.         
  314.     ;wait for return
  315. .wait        bsr    _GetKey
  316.         cmp.b    #3,d0            ;^C ?
  317.         beq    .end
  318.         cmp.b    #13,d0            ;CR ?
  319.         bne    .wait
  320.         bsr    _PrintLn
  321.  
  322.     ;read the disk image
  323. .readdisk    move.l    (gl_rd_device,GL),a0
  324.         bsr    _LoadDisk
  325.         move.l    d1,d4            ;D4 = size
  326.         move.l    d0,d5            ;D5 = buffer
  327.         beq    .end
  328.         
  329. NAMEBUFLEN = 16
  330.  
  331.     ;save disk image
  332.         lea    (_filefmt),a0        ;fmt
  333.         move.l    d7,-(a7)
  334.         move.l    a7,a1            ;args
  335.         sub.l    #NAMEBUFLEN,a7
  336.         move.l    a7,a2            ;buffer
  337.         moveq    #NAMEBUFLEN,d0        ;bufsize
  338.         bsr    _FormatString
  339.         move.l    (gl_rd_name,GL),d0
  340.         beq    .noname
  341.         move.l    d0,a2
  342. .noname        move.l    d4,d0            ;size
  343.         tst.l    (gl_rd_size,GL)
  344.         beq    .s
  345.         cmp.l    (gl_rd_size,GL),d0
  346.         bls    .s
  347.         move.l    (gl_rd_size,GL),d0
  348. .s        move.l    d5,a0            ;buffer
  349.         move.l    a2,a1            ;filename
  350.         bsr    _SaveFileMsg
  351.         add.l    #NAMEBUFLEN+4,a7
  352.         move.l    d0,d2            ;save return code
  353.         move.l    d5,a1
  354.         move.l    (gl_execbase,GL),a6
  355.         jsr    (_LVOFreeVec,a6)
  356.         tst.l    d2
  357.         beq    .end            ;if save file has failed
  358.  
  359.         bra    .nextdisk
  360.  
  361. .success    clr.l    (gl_rc,GL)
  362.  
  363. .end        move.l    (gl_rd_device,GL),d1
  364.         moveq    #0,d2
  365.         move.l    (gl_dosbase,GL),a6
  366.         jsr    (_LVOInhibit,a6)
  367.         
  368.         rts
  369.  
  370. ;##########################################################################
  371. ;----------------------------------------
  372. ; read disk
  373. ; IN:    A0 = CPTR device name
  374. ; OUT:    D0 = APTR loaded buffer OR NIL
  375. ;    D1 = LONG size of buffer
  376.  
  377.     NSTRUCTURE    local_dodisk,0
  378.         NSTRUCT    ld_di,devi_SIZEOF        ;DeviceInfo
  379.         NSTRUCT    ld_devname,DEVNAMELEN        ;devicename without ":"
  380.         NLABEL    ld_SIZEOF
  381.  
  382. _LoadDisk    movem.l    d2-d7/a6,-(a7)
  383.         link    LOC,#ld_SIZEOF
  384.         moveq    #0,d7                ;D7 = returncode (bufptr)
  385.         moveq    #0,d6                ;D6 = bufsize
  386.         
  387.     ;remove ":" from device name
  388.         lea    (ld_devname,LOC),a1
  389.         moveq    #DEVNAMELEN-1,d0
  390. .c        move.b    (a0)+,(a1)+
  391.         dbeq    d0,.c
  392.         clr.b    -(a1)
  393.         move.b    -(a1),d0
  394.         cmp.b    #":",d0
  395.         bne    .1
  396.         clr.b    (a1)
  397. .1
  398.     ;get geometry for device
  399.         lea    (ld_devname,LOC),a0
  400.         lea    (ld_di,LOC),a1
  401.         bsr    _GetDeviceInfo
  402.         tst.l    d0
  403.         beq    .nodevi
  404.  
  405.     ;print device name
  406.         lea    (_m_readdisk),a0
  407.         move.l    (ld_di+devi_Unit,LOC),-(a7)
  408.         pea    (ld_di+devi_Device,LOC)
  409.         pea    (ld_devname,LOC)
  410.         move.l    a7,a1
  411.         bsr    _PrintArgs
  412.         add.w    #12,a7
  413.         
  414.         move.l    (ld_di+devi_LowCyl,LOC),d2
  415.     IFEQ CPU-68020
  416.         mulu.l    (ld_di+devi_Surfaces,LOC),d2
  417.     ELSE
  418.         move.l    (ld_di+devi_Surfaces,LOC),d0
  419.         mulu32    d0,d2                    ;D2 = first track
  420.     ENDC
  421.  
  422.         move.l    (ld_di+devi_HighCyl,LOC),d3
  423.         sub.l    (ld_di+devi_LowCyl,LOC),d3
  424.         addq.l    #1,d3
  425.     IFEQ CPU-68020
  426.         mulu.l    (ld_di+devi_Surfaces,LOC),d3
  427.     ELSE
  428.         move.l    (ld_di+devi_Surfaces,LOC),d0
  429.         mulu32    d0,d3                    ;D3 = amount of tracks
  430.     ENDC
  431.  
  432.     IFEQ CPU-68020
  433.         move.l    (ld_di+devi_SizeBlock,LOC),d4
  434.         mulu.l    (ld_di+devi_BlocksPerTrack,LOC),d4
  435.     ELSE
  436.         move.l    (ld_di+devi_SizeBlock,LOC),d4
  437.         move.l    (ld_di+devi_BlocksPerTrack,LOC),d0
  438.         mulu32    d0,d4                    ;D4 = tracksize
  439.     ENDC
  440.  
  441.     ;print geometry
  442.         lea    (_m_diskgeo),a0
  443.         move.l    d3,d6
  444.         mulu32    d4,d6            ;disksize = cyls * heads * blktrk * blksize
  445.         move.l    d6,-(a7)
  446.         move.l    (ld_di+devi_HighCyl,LOC),-(a7)
  447.         move.l    (ld_di+devi_LowCyl,LOC),-(a7)
  448.         move.l    (ld_di+devi_BlocksPerTrack,LOC),-(a7)
  449.         move.l    (ld_di+devi_Surfaces,LOC),-(a7)
  450.         move.l    (ld_di+devi_SizeBlock,LOC),-(a7)
  451.         move.l    a7,a1
  452.         bsr    _PrintArgs
  453.         add.w    #6*4,a7
  454.  
  455.     ;calculate readlen / tracks
  456.         tst.l    (gl_rd_size,GL)
  457.         beq    .sok
  458.         cmp.l    (gl_rd_size,GL),d6
  459.         bls    .sok
  460.         moveq    #0,d3
  461.         moveq    #0,d6
  462. .add        addq.l    #1,d3                    ;D3 = amount of tracks
  463.         add.l    d4,d6                    ;D6 = bufsize
  464.         cmp.l    (gl_rd_size,GL),d6
  465.         blo    .add
  466. .sok
  467.         move.l    d6,d0
  468.         move.l    #MEMF_ANY,d1
  469.         move.l    (gl_execbase,GL),a6
  470.         jsr    (_LVOAllocVec,a6)
  471.         move.l    d0,d7
  472.         bne    .memok
  473.         moveq    #0,d0
  474.         lea    (_nomem),a0
  475.         lea    (_getdiskmem),a1
  476.         bsr    _PrintError
  477.         bra    .nomem
  478. .memok
  479.         lea    (ld_di+devi_Device,LOC),a0
  480.         move.l    a0,d0                    ;D0 = devicename
  481.         move.l    (ld_di+devi_Unit,LOC),d1        ;D1 = unit
  482.         move.l    d7,a1                    ;A1 = buffer
  483.         bsr    _ReadDisk
  484.         tst.l    d0
  485.         bne    .ok
  486.  
  487.         move.l    d7,a1
  488.         move.l    (gl_execbase,GL),a6
  489.         jsr    (_LVOFreeVec,a6)
  490.         moveq    #0,d6
  491.         moveq    #0,d7
  492. .ok
  493. .nomem
  494. .nodevi
  495.         move.l    d6,d1
  496.         move.l    d7,d0
  497.         unlk    LOC
  498.         movem.l    (a7)+,d2-d7/a6
  499.         rts
  500.  
  501. ;----------------------------------------
  502. ; Lesen Diskette
  503. ; IN:    D0 = APTR  device name
  504. ;    D1 = ULONG unit number
  505. ;    D2 = ULONG start track
  506. ;    D3 = ULONG tracks
  507. ;    D4 = ULONG bytes per track
  508. ;    A1 = APTR  buffer to read data in
  509. ;    GL = STRUCT globals
  510. ; OUT:    D0 = BOOL success
  511.  
  512.     NSTRUCTURE    local_readdisk,0
  513.         NAPTR    lrd_device
  514.         NULONG    lrd_unit
  515.         NAPTR    lrd_buffer
  516.         NAPTR    lrd_msgport
  517.         NBYTE    lrd_skipall
  518.         NALIGNLONG
  519.         LABEL    lrd_SIZEOF
  520.  
  521. _ReadDisk    movem.l    d2-d3/d7/a2/a6,-(a7)
  522.         link    LOC,#lrd_SIZEOF
  523.         move.l    d0,(lrd_device,LOC)
  524.         move.l    d1,(lrd_unit,LOC)
  525.         move.l    a1,(lrd_buffer,LOC)
  526.         sf    (lrd_skipall,LOC)
  527.         moveq    #0,d7                ;D7 = return (false)
  528.  
  529.         move.l    (gl_execbase,GL),a6        ;A6 = execbase
  530.         jsr    (_LVOCreateMsgPort,a6)
  531.         move.l    d0,(lrd_msgport,LOC)
  532.         bne    .portok
  533.         moveq    #0,d0
  534.         lea    (_noport),a0
  535.         sub.l    a1,a1
  536.         bsr    _PrintError
  537.         bra    .noport
  538. .portok        
  539.         move.l    (lrd_msgport,LOC),a0
  540.         move.l    #IOTD_SIZE,d0
  541.         jsr    (_LVOCreateIORequest,a6)
  542.         move.l    d0,a2                ;A2 = ioreq
  543.         tst.l    d0
  544.         bne    .ioreqok
  545.         moveq    #0,d0
  546.         lea    (_noioreq),a0
  547.         sub.l    a1,a1
  548.         bsr    _PrintError
  549.         bra    .noioreq
  550. .ioreqok
  551.         move.l    (lrd_device,LOC),a0
  552.         move.l    (lrd_unit,LOC),d0
  553.         move.l    a2,a1                ;ioreq
  554.         move.l    #0,d1                ;flags
  555.     move.l    d3,-(a7)                ;BUG in fucking mfm.device
  556.         jsr    (_LVOOpenDevice,a6)
  557.     move.l    (a7)+,d3                ;BUG in fucking mfm.device
  558.         tst.l    d0
  559.         beq    .deviceok
  560.         move.b    (IO_ERROR,a2),d0
  561.         lea    (_opendevice),a0
  562.         bsr    _PrintErrorTD
  563.         bra    .nodevice
  564. .deviceok
  565.  
  566.     ;get actual diskchange count
  567.         move.l    a2,a1                ;ioreq
  568.         move.w    #TD_CHANGENUM,(IO_COMMAND,a1)
  569.         jsr    (_LVODoIO,a6)
  570.         move.l    (IO_ACTUAL,a2),(IOTD_COUNT,a2)
  571.  
  572.         add.l    d2,d3                ;D3 = last track
  573.  
  574.         bsr    _PrintLn
  575. .loop        lea    (_diskprogress),a0        ;output progress
  576.         move.l    d3,-(a7)
  577.         sub.l    d2,(a7)
  578.         subq.l    #1,(a7)
  579.         move.l    d2,-(a7)
  580.         move.l    a7,a1
  581.         bsr    _PrintArgs
  582.         addq.l    #8,a7
  583.         
  584.     ;check for CTRL-C
  585.         bsr    _CheckBreak
  586.         tst.l    d0
  587.         bne    .break
  588.         
  589.     ;check if track should be skipped
  590.         tst.b    (gl_skip,GL,d2.w)
  591.         bne    .skip
  592.  
  593.     ;read the track
  594.         clr.b    (IO_ERROR,a2)
  595.         move.w    #ETD_READ,(IO_COMMAND,a2)
  596.         move.l    d4,(IO_LENGTH,a2)        ;bytes per track
  597.         move.l    d2,d0
  598.         mulu32    d4,d0
  599.         move.l    d0,(IO_OFFSET,a2)        ;begin at disk (offset)
  600.         add.l    (lrd_buffer,LOC),d0
  601.         move.l    d0,(IO_DATA,a2)            ;dest buf
  602.         move.l    a2,a1
  603.         move.l    (gl_execbase,GL),a6
  604.         jsr    (_LVODoIO,a6)
  605.         move.b    (IO_ERROR,a2),d0
  606.         beq    .readok
  607.         lea    (_readdisk),a0
  608.         bsr    _PrintErrorTD
  609.         
  610.         cmp.b    #TDERR_DiskChanged,(IO_ERROR,a2)
  611.         bne    .notchg
  612.         move.l    a2,a1                ;ioreq
  613.         move.w    #TD_CHANGENUM,(IO_COMMAND,a1)
  614.         jsr    (_LVODoIO,a6)
  615.         move.l    (IO_ACTUAL,a2),(IOTD_COUNT,a2)
  616. .notchg
  617.         tst.l    (gl_rd_pedantic,GL)
  618.         bne    .break
  619.         
  620.         tst.b    (lrd_skipall,LOC)
  621.         bne    .skip
  622.  
  623.         move.l    (gl_stdin,GL),d1
  624.         move.l    (gl_dosbase,GL),a6
  625.         jsr    (_LVOIsInteractive,a6)
  626.         tst.l    d0
  627.         beq    .skip
  628.  
  629.         lea    (_tryagain),a0
  630.         bsr    _Print
  631.         bsr    _FlushOutput
  632.         
  633. .wait        bsr    _GetKey
  634.         cmp.b    #3,d0                ;Ctrl-C
  635.         beq    .break
  636.         UPPER    d0
  637.         cmp.b    #"R",d0
  638.         beq    .waitend
  639.         cmp.b    #"S",d0
  640.         beq    .waitend
  641.         cmp.b    #"A",d0
  642.         beq    .waitend
  643.         cmp.b    #"Q",d0
  644.         beq    .waitend
  645.         cmp.b    #13,d0                ;Return
  646.         bne    .wait
  647.         
  648. .waitend    lsl.w    #8,d0
  649.         or.w    #10,d0
  650.         clr.w    -(a7)
  651.         move.w    d0,-(a7)
  652.         move.l    a7,a0
  653.         bsr    _Print
  654.         move.l    (a7)+,d0
  655.         rol.l    #8,d0
  656.         cmp.b    #"R",d0
  657.         beq    .loop
  658.         cmp.b    #"S",d0
  659.         beq    .skip
  660.         cmp.b    #"Q",d0
  661.         beq    .break
  662.         cmp.b    #13,d0                ;Return
  663.         beq    .break
  664.  
  665.     ;skip all errors
  666.         st    (lrd_skipall,LOC)
  667.  
  668. .skip
  669.     ;fill track data area with pattern "TDIC"
  670.         move.l    d2,d0
  671.         mulu32    d4,d0
  672.         add.l    (lrd_buffer,LOC),d0
  673.         move.l    d0,a0
  674.         move.l    d4,d0
  675.         lsr.l    #2,d0
  676. .fill        move.l    #"TDIC",(a0)+
  677.         subq.l    #1,d0
  678.         bne    .fill
  679.         
  680.     ;next track
  681. .readok        addq.l    #1,d2
  682.         cmp.l    d2,d3
  683.         bne    .loop
  684.  
  685.         bsr    _PrintLn
  686.         moveq    #-1,d7
  687. .break
  688.  
  689.     ;switch drive motor off
  690.         move.l    a2,a1
  691.         move.l    #0,(IO_LENGTH,a1)
  692.         move.w    #ETD_MOTOR,(IO_COMMAND,a1)
  693.         move.l    (gl_execbase,GL),a6
  694.         jsr    (_LVODoIO,a6)
  695.  
  696.         move.l    a2,a1
  697.         jsr    (_LVOCloseDevice,a6)
  698.         
  699. .nodevice    move.l    a2,a0
  700.         jsr    (_LVODeleteIORequest,a6)
  701.         
  702. .noioreq    move.l    (lrd_msgport,LOC),a0
  703.         jsr    (_LVODeleteMsgPort,a6)
  704.         
  705. .noport        move.l    d7,d0                ;return code
  706.         unlk    LOC
  707.         movem.l    (a7)+,d2-d3/d7/a2/a6
  708.         rts
  709.  
  710. ;##########################################################################
  711.  
  712. _defdev        dc.b    "DF0:",0
  713. _insdisk    dc.b    10,"Insert disk %ld into drive %s and press RETURN (^C to cancel) ...",0
  714. _tryagain    dc.b    "Retry/Skip/skip All/Quit (r/s/a/Q): ",0
  715. _filefmt    dc.b    "Disk.%ld",0
  716. _txt_badtracks    dc.b    "Invalid SKIPTRACK/K specification",10,0
  717.  
  718. ;Messages
  719. _m_readdisk    dc.b    "read from ",155,"1m%s",155,"22m: (%s %ld)",10,0
  720. _m_diskgeo    dc.b    "(blksize=%ld heads=%ld blktrk=%ld lcyl=%ld hcyl=%ld) size=%ld",10,0
  721. _m_savedisk    dc.b    "save disk as ",155,"3m%s ",155,"23m",10,0
  722. _m_savefile    dc.b    "save file ",155,"3m%s ",155,"23m",10,0
  723. _diskprogress    dc.b    11,155,"Kreading track %ld left %ld",10,0
  724. _withsize    dc.b    "limited reading of $%lx=%ld bytes",10,0
  725.  
  726. ; Errors
  727. _nomem        dc.b    "not enough free store",0
  728. _noport        dc.b    "can't create MessagePort",0
  729. _noioreq    dc.b    "can't create IO-Request",0
  730. _nodev        dc.b    "device doesn't exist",0
  731. _baddev        dc.b    "cannot handle this device",0
  732. _badsize    dc.b    "illegal argument for SIZE/K",10,0
  733.  
  734. ; Operationen
  735. _readargs    dc.b    "read arguments",0
  736. _getdiskmem    dc.b    "alloc mem for disk",0
  737. _readdisk    dc.b    "read disk",0
  738. _getdevinfo    dc.b    "get dev info",0
  739. _opendevice    dc.b    "open device",0
  740.  
  741. ;subsystems
  742. _dosname    DOSNAME
  743.  
  744. _template    dc.b    "DEVICE"        ;name of device (default "DF0:)
  745.         dc.b    ",NAME"            ;name of image, implies FD=1 and LD=1
  746.         dc.b    ",SKIPTRACK/K"        ;dont read these tracks
  747.         dc.b    ",SIZE/K"        ;number of bytes
  748.         dc.b    ",FD=FIRSTDISK/K/N"    ;number of first disk
  749.         dc.b    ",LD=LASTDISK/K/N"    ;number of last disk
  750.         dc.b    ",PEDANTIC/S"        ;quit on unreadable tracks
  751.         dc.b    0
  752.  
  753. _ver        VER
  754.         dc.b    " ",155,"1mD",155,"22misk ",155,"1mI",155,"22mmage ",155,"1mC",155,"22mreator by Bert Jahn"
  755.         dc.b    10,0
  756.  
  757. ;##########################################################################
  758.  
  759.     END
  760.  
  761.